/*
 * Created on 2006-8-2 上午07:14:35
 */
package cn.com.sbell.vss.csg.heartbeat;

import java.io.File;
import java.io.FileInputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteOrder;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderAdapter;
import org.apache.mina.filter.codec.ProtocolDecoderException;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;

public class HeartBeatMessageDecoder extends ProtocolDecoderAdapter {

	private final static Log log = LogFactory.getLog(HeartBeatMonitor.class); 

	private final static int HEAD_LENGTH = 4;
	private final static int ACK_TYPE = 0;
	private final static int SERVER_NAME = 1;
	private final static int SERVER_ID = 2;
	private final static int SERVER_IP = 3;
	private final static int INTERVAL = 4;
	
	//增加设备接入码的属性值为9
	private final static int PU_PASSWORD=9;
	private final static int SERVER_TYPE=10;
	
	public void decode(IoSession session, ByteBuffer buffer,
			ProtocolDecoderOutput out) throws Exception {
		
		HeartBeatMessage message = new HeartBeatMessage();
		int size = buffer.remaining();
		if(size <= HEAD_LENGTH){
			throw new ProtocolDecoderException("Bad buffer, head incorrect!");
		}
//		if(size <= HEAD_LENGTH || size != buffer.getShort(2))
//			throw new ProtocolDecoderException("Bad buffer! size = " + size);
		buffer.order(ByteOrder.BIG_ENDIAN);
		short totalLength = buffer.getShort(2);
		System.out.println("BIG_ENDIAN get total length = "+totalLength);
		if(size != totalLength){
			buffer.order(ByteOrder.LITTLE_ENDIAN);
			totalLength = buffer.getShort(2);
			System.out.println("LITTLE_ENDIAN get total length = "+totalLength);
			if(size != totalLength){
				throw new ProtocolDecoderException("Bad buffer! size = " + size);
			}
		}
		message.setMessageType(buffer.get(1));
		buffer.get(new byte[HEAD_LENGTH]);
		
		while(buffer.hasRemaining()){
			int type = buffer.get();
			buffer.get();
			int length = buffer.getShort();
			byte[] entity = new byte[length - 4];
			buffer.get(entity);
			switch(type){
				case ACK_TYPE:
					processACKType(entity, message);
					break;
				case SERVER_NAME:
					processServerName(entity, message);
					break;
				case SERVER_ID:
					processServerId(entity, message);
					break;
				case SERVER_IP:
					processServerIp(entity, message);
					break;
				case INTERVAL:
					processPeriod(entity, message);
					break;
				case PU_PASSWORD:
					processAccessPassword(entity, message);
					break;
				case SERVER_TYPE:
					processServerType(entity,message);
					break;
				default:
					throw new ProtocolDecoderException("No such property: type=" + type);
			}
		}		
		out.write(message);
	}
	
	private static void processACKType(byte[] entity, HeartBeatMessage message){
		boolean ack = false;
		for(int i=0;i<entity.length;i++){
			ack = (ack || entity[i]==1);
		}
		message.setNeedAcknowledge(ack);
	}
	private static void processServerName(byte[] entity, HeartBeatMessage message){
		String name = null;
		try {
			name = new String(entity, "gb2312").trim();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		message.setServerName(name);
	}
	private static void processServerId(byte[] entity, HeartBeatMessage message){
		String id = new String(entity).trim();
		message.setServerId(id);
	}
	private static void processServerIp(byte[] entity, HeartBeatMessage message){
		if(log.isDebugEnabled()){
			log.debug(" *** process server ip ***");
			log.debug(entity);
			log.debug(message);
		}
		
		StringBuffer host = new StringBuffer();
		for(int i=0;i<4;i++){
			host.append(0xFF & entity[i]);
			host.append(".");
		}
		message.setServerIp(host.substring(0, host.length()-1));
		ByteBuffer port = ByteBuffer.wrap(entity, 4, 2);
		message.setPort(port.getShort());
		
		if(log.isDebugEnabled()){			
			log.debug(entity);
			log.debug(message);
			log.debug(" *** process server ip ***");
		}

	}
	private static void processPeriod(byte[] entity, HeartBeatMessage message){
		ByteBuffer period = ByteBuffer.wrap(entity);
		message.setPeriod(period.getShort());
	}
	
	//增加设备接入码的解析
	private static void processAccessPassword(byte[] entity, HeartBeatMessage message){
		String accessPassword=new String(entity).trim();
		message.setAccessPassword(accessPassword);
	}
	private static void processServerType(byte[] entity, HeartBeatMessage message)
	{
		String serverType=new String(entity).trim();
		message.setServerType(serverType);
		if(log.isDebugEnabled())
		{
			log.debug("serverType="+new String(entity));
		}
	}
	public static void main(String[] args) throws Exception{
		HeartBeatMessageDecoder decoder = new HeartBeatMessageDecoder();
		SocketDemo socket = new SocketDemo();
		decoder.decode(null, ByteBuffer.wrap(socket.createTCPdata()), null);
	}
}
